﻿/*
-----------------------------------------------------------------------------------------------------------------------------
Filename: WinAPI.cs
Description: Gives access to various API functions.

Created: Sep 17, 2010
Updated: Apr 06, 2011

Copyright (C) 2009-2011 Eyal Kalderon and contibutors.
-----------------------------------------------------------------------------------------------------------------------------
*/

// Make all necessary declarations.
using System;
using System.Text;
using System.Runtime.InteropServices;

// Add this file to the namespace WinAPI.
namespace WinAPI
{
    /// <summary>
    /// Encapsulates the native API.
    /// </summary>

    /*
    NOTE: Just to be helpful, I will put a list of all definitions
    this wrapper creates, to make creating new API-based functions
    easier because this file will hold ALL of the API definitions/enums
    to get these functions to work. Here they are:
    
     * ACCESS_MASK
     * CLOSEDESKTOP
     * CREATEDESKTOP
     * CREATEPROCESS
     * ENABLEWINDOW
     * ENUMDESKTOPS
     * EnumDesktopsDelegate
     * ENUMDESKTOPWINDOWS
     * EnumDesktopWindowsDelegate
     * ENUMWINDOWS
     * FINDWINDOW
     * FINDWINDOWEX
     * FINDWINDOWBYCAPTION
     * GETWINDOW
     * GETWINDOWTEXT
     * GetUserObjectInformation
     * GETTHREADDESKTOP
     * MAX_PATH
     * MAX_TITLE
     * OPENDESKTOP
     * OPENINPUTDESKTOP
     * PROCESS_INFORMATION
     * SECURITY_ATTRIBUTES
     * SETTHREADDESKTOP
     * SHOWWINDOW
     * SPI_GETDESKTOPWALLPAPER
     * SPI_GETWORKAREA
     * SPI_SETDESKTOPWALLPAPER
     * SPI_SETWORKAREA
     * SPIF_SENDWININICHANGE
     * SPIF_UPDATEINIFILE
     * STARTUPINFO
     * SWITCHDESKTOP
     * RECT (custom struct which represents a rectangle)
     * rights (custom long which contains desktop-manipulation rights)
     * SHOWWINDOW
     * ShowWindowStyle
    */

    // Begin the Functions class.
    public class Functions
    {
        // Make a few needed variables.
        #region Required Declarations
        // Create needed desktop access rights...
        private const int DESKTOP_CREATEWINDOW = 0x0002;
        private const int DESKTOP_ENUMERATE = 0x0040;
        private const int DESKTOP_WRITEOBJECTS = 0x0080;
        private const int DESKTOP_SWITCHDESKTOP = 0x0100;
        private const int DESKTOP_CREATEMENU = 0x0004;
        private const int DESKTOP_HOOKCONTROL = 0x0008;
        private const int DESKTOP_READOBJECTS = 0x0001;
        private const int DESKTOP_JOURNALRECORD = 0x0010;
        private const int DESKTOP_JOURNALPLAYBACK = 0x0020;

        // ... and save them into a public int called "rights"
        // so it can be universally accessed.
        public const int rights =
            DESKTOP_CREATEWINDOW |
            DESKTOP_ENUMERATE |
            DESKTOP_WRITEOBJECTS |
            DESKTOP_SWITCHDESKTOP |
            DESKTOP_CREATEMENU |
            DESKTOP_HOOKCONTROL |
            DESKTOP_READOBJECTS |
            DESKTOP_JOURNALRECORD |
            DESKTOP_JOURNALPLAYBACK;

        // Make some miscellaneous variables...
        public const int GW_CHILD = 5;
        public const int MAX_TITLE = 255;
        public delegate bool EnumDelegate(IntPtr hWnd, int lParam);
        public delegate bool EnumDesktopWindowsProc(IntPtr desktopHandle, IntPtr lParam);
        public delegate bool EnumWindowsProc(int hWnd, int lParam);
        public const int SW_HIDE = 0;
        public const int SW_SHOW = 5;

        #endregion

        //---------------------------------------------------------------------------------------------------------------------
        // Desktop and window manipulation API definitions.
        //---------------------------------------------------------------------------------------------------------------------
        #region Definitions/Enums

        // Different imported functions from user32.dll.
        #region Dll Imports
        [DllImport("user32.dll")]
        public static extern long EnableWindow(long hwnd, long fEnable);

        [DllImport("user32.dll")]
        public static extern int EnumWindows(IntPtr hwnd, int lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        public static extern int FindWindowByCaption(int ZeroOnly, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

        [DllImport("user32.dll")]
        public static extern long GetWindow(long hwnd, long wCmd);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref RECT pvParam, uint fWinIni);

        [DllImport("user32.dll")]
        public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
            int Y, int cx, int cy, uint uFlags);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
        #endregion

        //---------------------------------------------------------------------------------------------------------------------

        //
        // Definition for IsWindowVisible.
        #region IsWindowVisible
        [DllImport("user32.dll")]
        static extern bool IsWindowVisible(IntPtr hWnd);
        #endregion

        // Definition for MAX_PATH for GetDesktopWallpaperPath.
        #region MAX_PATH
        public static readonly int MAX_PATH = 260;
        #endregion

        // Definition for SPI_GETDESKWALLPAPER for GetDesktopWallpaperPath.
        #region SPI_GETDESKTOPWALLPAPER
        public static readonly UInt32 SPI_GETDESKWALLPAPER = 0x73;
        #endregion

        // Definition for SPI_SETWORKAREA for SystemParametersInfo.
        #region SPI_GETWORKAREA
        public enum SPI_GETWORKAREA : int
        {
            SPI_GETWORKAREA = 0x0030
        }
        #endregion

        // Definition for SPI_SETDESKWALLPAPER for SetDesktopWallpaper.
        #region SPI_SETDESKTOPWALLPAPER
        public static readonly UInt32 SPI_SETDESKWALLPAPER = 0x14;
        #endregion

        // Definition for SPI_SETWORKAREA for SystemParametersInfo.
        #region SPI_SETWORKAREA
        public enum SPI_SETWORKAREA : int
        {
            SPI_SETWORKAREA = 0x002F,
        }
        #endregion

        // Definition for SPIF_SETDESKWALLPAPER for SetDesktopWallpaper.
        #region SPIF_SENDWININICHANGE
        public static readonly UInt32 SPIF_SENDWININICHANGE = 0x02;
        #endregion

        // Definition for SPIF_UPDATEINIFILE for SetDesktopWallpaper.
        #region SPIF_UPDATEINIFILE
        public static readonly UInt32 SPIF_UPDATEINIFILE = 0x01;
        #endregion

        // Definition for RECT for general API functions.
        #region RECT
        /// <summary>
        /// Struct which represents 4 points which form a rectangle.
        /// </summary>
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }
        #endregion

        // Definition for WindowShowStyle for ShowWindow.
        #region WindowShowStyle
        public enum WindowShowStyle : int
        {
            Hide = 0,
            ShowNormal = 1,
            ShowMinimized = 2,
            ShowMaximized = 3,
            Maximize = 3,
            ShowNormalNoActivate = 4,
            Show = 5,
            Minimize = 6,
            ShowMinNoActivate = 7,
            ShowNoActivate = 8,
            Restore = 9,
            ShowDefault = 10,
            ForceMinimized = 11
        }
        #endregion

        #endregion

        //---------------------------------------------------------------------------------------------------------------------
        // Virtual desktop API definitions.
        //---------------------------------------------------------------------------------------------------------------------
        #region Definitions/Enums

        // Enum for ACCESS_MASK for CreateDesktop.
        #region ACCESS_MASK
        public enum ACCESS_MASK : uint
        {
            DELETE = 0x00010000,
            READ_CONTROL = 0x00020000,
            WRITE_DAC = 0x00040000,
            WRITE_OWNER = 0x00080000,
            SYNCHRONIZE = 0x00100000,

            STANDARD_RIGHTS_REQUIRED = 0x000f0000,

            STANDARD_RIGHTS_READ = 0x00020000,
            STANDARD_RIGHTS_WRITE = 0x00020000,
            STANDARD_RIGHTS_EXECUTE = 0x00020000,

            STANDARD_RIGHTS_ALL = 0x001f0000,

            SPECIFIC_RIGHTS_ALL = 0x0000ffff,

            ACCESS_SYSTEM_SECURITY = 0x01000000,

            MAXIMUM_ALLOWED = 0x02000000,

            GENERIC_READ = 0x80000000,
            GENERIC_WRITE = 0x40000000,
            GENERIC_EXECUTE = 0x20000000,
            GENERIC_ALL = 0x10000000,

            DESKTOP_READOBJECTS = 0x00000001,
            DESKTOP_CREATEWINDOW = 0x00000002,
            DESKTOP_CREATEMENU = 0x00000004,
            DESKTOP_HOOKCONTROL = 0x00000008,
            DESKTOP_JOURNALRECORD = 0x00000010,
            DESKTOP_JOURNALPLAYBACK = 0x00000020,
            DESKTOP_ENUMERATE = 0x00000040,
            DESKTOP_WRITEOBJECTS = 0x00000080,
            DESKTOP_SWITCHDESKTOP = 0x00000100,

            WINSTA_ENUMDESKTOPS = 0x00000001,
            WINSTA_READATTRIBUTES = 0x00000002,
            WINSTA_ACCESSCLIPBOARD = 0x00000004,
            WINSTA_CREATEDESKTOP = 0x00000008,
            WINSTA_WRITEATTRIBUTES = 0x00000010,
            WINSTA_ACCESSGLOBALATOMS = 0x00000020,
            WINSTA_EXITWINDOWS = 0x00000040,
            WINSTA_ENUMERATE = 0x00000100,
            WINSTA_READSCREEN = 0x00000200,

            WINSTA_ALL_ACCESS = 0x0000037f
        }
        #endregion

        // Definition for EnumDesktopsDelegate for EnumDesktops.
        #region EnumDesktopsDelegate
        public delegate bool EnumDesktopsDelegate(string desktop, IntPtr lParam);
        #endregion

        // Definition for EnumDesktopWindowsDelegate for EnumDesktops.
        #region EnumDesktopWindowsDelegate
        public delegate bool EnumDesktopWindowsDelegate(IntPtr hWnd, int lParam);
        #endregion

        // --------------------------

        #region API Functions Definitions

        // Create definition "CloseDesktop".
        #region CLOSEDESKTOP
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll")]

        // Define the CloseDesktop function.
        public static extern bool CloseDesktop(IntPtr hDesktop);
        #endregion

        // Create definition "CreateDesktop".
        #region CREATEDESKTOP
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll")]

        // Define the CreateDesktop function.
        public static extern IntPtr CreateDesktop(
            string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags, int dwDesiredAccess, IntPtr lpsa);
        #endregion

        // Create definition "EnumDesktops".
        #region ENUMDESKTOPS
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll")]

        // Define the function EnumDesktops.
        public static extern bool EnumDesktops(IntPtr hwinsta, EnumDesktopsDelegate
        lpEnumFunc, IntPtr lParam);
        #endregion

        // Create definition "EnumDesktopWindows".
        #region ENUMDESKTOPWINDOWS
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll")]

        // Define the function EnumDesktops.
        public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDesktopWindowsDelegate lpfn, IntPtr lParam);
        #endregion

        // Create definition "GetThreadDesktop".
        #region GETTHREADDESKTOP
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll", SetLastError = true)]

        // Define the function GetThreadDesktop.
        public static extern IntPtr GetThreadDesktop(uint dwThreadId);
        #endregion

        // Create definition "GetUserObjectInformation".
        #region GetUserObjectInformation
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll")]

        // Define the function GetUserObjectInformation.
        public static extern bool GetUserObjectInformation(
            IntPtr hObj, int nIndex, IntPtr pvInfo, int nLength, ref int lpnLengthNeeded);
        #endregion

        // Create definition "OpenDesktop".
        #region OPENDESKTOP
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll")]

        // Define the function OpenDesktop.
        public static extern IntPtr OpenDesktop(
            string lpszDesktop, int dwFlags, bool fInherit, int dwDesiredAccess);
        #endregion

        // Create definition "OpenInputDesktop".
        #region OPENINPUTDESKTOP
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll")]

        // Define the OpenInputDesktop function.
        public static extern IntPtr OpenInputDesktop(
            int dwFlags, bool fInherit, int dwDesiredAccess);
        #endregion

        // Create definition "SetThreadDesktop".
        #region SETTHREADDESKTOP
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll", SetLastError = true)]

        // Define the function SetThreadDesktop.
        public static extern bool SetThreadDesktop(IntPtr hDesktop);
        #endregion

        // Create definition "SwitchDesktop".
        #region SWITCHDESKTOP
        // Import user32.dll with the desktops API.
        [DllImport("user32.dll")]

        // Define the SwitchDesktop function.
        public static extern bool SwitchDesktop(IntPtr hDesktop);
        #endregion

        #endregion

        #endregion

        //---------------------------------------------------------------------------------------------------------------------
        // Process manipulation API definitions.
        //---------------------------------------------------------------------------------------------------------------------
        #region Definitions/Enums

        // Definition for NORMAL_PRIORITY_CLASS for CreateProcess.
        #region NORMAL_PRIORITY_CLASS
        public const int NORMAL_PRIORITY_CLASS = 0x00000020;
        #endregion

        // Definition for PROCESS_INFORMATION for CreateProcess.
        #region PROCESS_INFORMATION
        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }
        #endregion

        // Definition for SECURITY_ATTRIBUTES for CreateProcess.
        #region SECURITY_ATTRIBUTES
        public class SECURITY_ATTRIBUTES
        {
            public int nLength;
            public byte lpSecurityDescriptor;
            public int bInheritHandle;
        }
        #endregion

        // Definition for STARTUPINFO for CreateProcess.
        #region STARTUPINFO
        [StructLayout(LayoutKind.Sequential)]
        public struct STARTUPINFO
        {
            public int cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public int dwX;
            public int dwY;
            public int dwXSize;
            public int dwYSize;
            public int dwXCountChars;
            public int dwYCountChars;
            public int dwFillAttribute;
            public int dwFlags;
            public short wShowWindow;
            public short cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
        #endregion

        #endregion

        #region API Functions Definitions

        // Create definition "CreateProcess".
        #region CREATEPROCESS
        // Import kernel32.dll with the kernel process API.
        [DllImport("kernel32.dll")]

        // Define function "CreateProcess".
        public static extern bool CreateProcess(
            string lpApplicationName,
            string lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool bInheritHandles,
            int dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            ref PROCESS_INFORMATION lpProcessInformation
        );
        #endregion

        #endregion
    }
}
